bitkeeper revision 1.1509.1.4 (4294ddbdS0zXLWNl7GY3vmRtzKddcQ)
authordjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 25 May 2005 20:19:09 +0000 (20:19 +0000)
committerdjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 25 May 2005 20:19:09 +0000 (20:19 +0000)
Implement virtual short format VHPT walker

Signed-off-by: Matthew Chapman <matthewc@hp.com>
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>

xen/arch/ia64/patch/linux-2.6.11/kregs.h
xen/arch/ia64/process.c
xen/arch/ia64/vcpu.c

index dab91c8b07f40cb989426db19f70e3c24c62c391..1268171987e0129f5da9fcfe6a85a5a838bf9339 100644 (file)
@@ -45,7 +45,7 @@
  #define IA64_ISR_CODE_LFETCH  4
  #define IA64_ISR_CODE_PROBEF  5
  
-+#ifdef CONFIG_VTI
++#ifdef XEN
 +/* Interruption Function State */
 +#define IA64_IFS_V_BIT                63
 +#define IA64_IFS_V    (__IA64_UL(1) << IA64_IFS_V_BIT)
@@ -60,6 +60,6 @@
 +#define IA64_PTA_SIZE   (__IA64_UL(0x3f) << IA64_PTA_SIZE_BIT)
 +#define IA64_PTA_VF     (__IA64_UL(1) << IA64_PTA_VF_BIT)
 +#define IA64_PTA_BASE   (__IA64_UL(0) - ((__IA64_UL(1) << IA64_PTA_BASE_BIT)))
-+#endif // CONFIG_VTI
++#endif
 +
  #endif /* _ASM_IA64_kREGS_H */
index 50534abdbf847004ba5cbddbc82dc959fb76d211..60a2f30f76699a683c1b4f794788aadba84c7367 100644 (file)
@@ -153,7 +153,8 @@ void reflect_interruption(unsigned long ifa, unsigned long isr, unsigned long it
                }
                vector &= ~0xf;
                if (vector != IA64_DATA_TLB_VECTOR &&
-                   vector != IA64_ALT_DATA_TLB_VECTOR) {
+                   vector != IA64_ALT_DATA_TLB_VECTOR &&
+                   vector != IA64_VHPT_TRANS_VECTOR) {
 panic_domain(regs,"psr.ic off, delivering fault=%lx,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n",
        vector,regs->cr_iip,ifa,isr,PSCB(ed,iip));
                        
@@ -167,15 +168,12 @@ panic_domain(regs,"psr.ic off, delivering fault=%lx,iip=%p,ifa=%p,isr=%p,PSCB.ii
                return;
 
        }
-       if ((vector & 0xf) != IA64_FORCED_IFA) PSCB(ed,ifa) = ifa;
-       else ifa = PSCB(ed,ifa);
+       if ((vector & 0xf) == IA64_FORCED_IFA)
+               ifa = PSCB(ed,tmp[0]);
        vector &= ~0xf;
-       if (vector == IA64_DATA_TLB_VECTOR
-               || vector == IA64_ALT_DATA_TLB_VECTOR
-               || vector == IA64_INST_TLB_VECTOR
-               || vector == IA64_ALT_INST_TLB_VECTOR) {
+       PSCB(ed,ifa) = ifa;
+       if (vector < IA64_DATA_NESTED_TLB_VECTOR) /* VHPT miss, TLB miss, Alt TLB miss */
                vcpu_thash(ed,ifa,&PSCB(current,iha));
-       }
        PSCB(ed,unat) = regs->ar_unat;  // not sure if this is really needed?
        PSCB(ed,precover_ifs) = regs->cr_ifs;
        vcpu_bsw0(ed);
@@ -320,7 +318,7 @@ void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_reg
        unsigned long psr = regs->cr_ipsr, mask, flags;
        unsigned long iip = regs->cr_iip;
        // FIXME should validate address here
-       unsigned long pteval, mpaddr;
+       unsigned long iha, pteval, mpaddr;
        unsigned long lookup_domain_mpa(struct domain *,unsigned long);
        unsigned long is_data = !((isr >> IA64_ISR_X_BIT) & 1UL);
        unsigned long vector;
@@ -346,8 +344,8 @@ void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_reg
                // FIXME should validate mpaddr here
                if (d == dom0) {
                        if (address < dom0_start || address >= dom0_start + dom0_size) {
-                               //printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, iip=%p! continuing...\n",address,iip);
-                               //printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, old iip=%p!\n",address,current->vcpu_info->arch.iip);
+                               printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, iip=%p! continuing...\n",address,iip);
+                               printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, old iip=%p!\n",address,current->vcpu_info->arch.iip);
                                tdpfoo();
                        }
                }
@@ -365,7 +363,7 @@ void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_reg
 
        if (handle_lazy_cover(current, isr, regs)) return;
 if (!(address>>61)) {
-panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, itc=%p (spinning...)\n",address,iip,ia64_get_itc());
+panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, b0=%p, itc=%p (spinning...)\n",address,iip,regs->b0,ia64_get_itc());
 }
        if ((isr & IA64_ISR_SP)
            || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
@@ -378,9 +376,37 @@ panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, itc=%p (spinning...)\n",addr
                ia64_psr(regs)->ed = 1;
                return;
        }
-       vector = vcpu_get_rr_ve(current, address) ? 
-                       (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR)
-                       : (is_data ? IA64_ALT_DATA_TLB_VECTOR : IA64_ALT_INST_TLB_VECTOR);
+
+       if (vcpu_get_rr_ve(current, address) && (PSCB(current,pta) & IA64_PTA_VE))
+       {
+               if (PSCB(current,pta) & IA64_PTA_VF)
+               {
+                       /* long format VHPT - not implemented */
+                       vector = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR;
+               }
+               else
+               {
+                       /* short format VHPT */
+                       vcpu_thash(current, address, &iha);
+                       if (__copy_from_user(&pteval, iha, sizeof(pteval)) == 0)
+                       {
+                               /* 
+                                * Optimisation: this VHPT walker aborts on not-present pages
+                                * instead of inserting a not-present translation, this allows
+                                * vectoring directly to the miss handler.
+       \                        */
+                               if (pteval & _PAGE_P)
+                               {
+                                       pteval = translate_domain_pte(pteval,address,itir);
+                                       vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(itir>>2)&0x3f);
+                                       return;
+                               }
+                               else vector = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR;
+                       }
+                       else vector = IA64_VHPT_TRANS_VECTOR;
+               }
+       }
+       else vector = is_data ? IA64_ALT_DATA_TLB_VECTOR : IA64_ALT_INST_TLB_VECTOR;
        reflect_interruption(address, isr, itir, regs, vector);
 }
 
@@ -744,11 +770,7 @@ ia64_handle_privop (unsigned long ifa, struct pt_regs *regs, unsigned long isr,
        // AND ACTUALLY reflect_interruption doesn't use it anyway!
        itir = vcpu_get_itir_on_fault(ed,ifa);
        vector = priv_emulate(current,regs,isr);
-       if (vector == IA64_RETRY) {
-               reflect_interruption(ifa,isr,itir,regs,
-                       IA64_ALT_DATA_TLB_VECTOR | IA64_FORCED_IFA);
-       }
-       else if (vector != IA64_NO_FAULT && vector != IA64_RFI_IN_PROGRESS) {
+       if (vector != IA64_NO_FAULT && vector != IA64_RFI_IN_PROGRESS) {
                reflect_interruption(ifa,isr,itir,regs,vector);
        }
 }
index f8e4a3867c91f34779ba829900bc9cca63c7afe5..fb9db8a35fe8f4f1df319861ee7ff9aa64958a0f 100644 (file)
@@ -1117,7 +1117,7 @@ Privileged operation emulation routines
 
 IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa)
 {
-       PSCB(vcpu,ifa) = ifa;   // privop traps don't set ifa so do it here
+       PSCB(vcpu,tmp[0]) = ifa;        // save ifa in vcpu structure, then specify IA64_FORCED_IFA
        return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR : IA64_ALT_DATA_TLB_VECTOR) | IA64_FORCED_IFA;
 }
 
@@ -1206,7 +1206,7 @@ IA64FAULT vcpu_thash(VCPU *vcpu, UINT64 vadr, UINT64 *pval)
                ((pta_base >> 15) & 0x3fffffffffff) & compMask_60_15;
        UINT64 VHPT_addr2b =
                ((VHPT_offset >> 15) & 0x3fffffffffff) & Mask_60_15;;
-       UINT64 VHPT_addr3 = VHPT_offset & 0x3fff;
+       UINT64 VHPT_addr3 = VHPT_offset & 0x7fff;
        UINT64 VHPT_addr = VHPT_addr1 | ((VHPT_addr2a | VHPT_addr2b) << 15) |
                        VHPT_addr3;